package com.darsystems.foghourz.server;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Set;
import java.util.TimeZone;
import java.util.TreeMap;
import java.util.Map.Entry;
import java.util.logging.Logger;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import com.darsystems.foghourz.client.DailyWork;

public class Interval {

	/*
	 <?xml version="1.0" encoding="UTF-8"?>
	 <response>
	    <intervals>
	       <interval>
	          <ixInterval>229</ixInterval>
	          <ixPerson>2</ixPerson>
	          <ixBug>87</ixBug>
	          <dtStart>2009-09-23T17:41:17Z</dtStart>
	          <dtEnd>2009-09-23T18:18:11Z</dtEnd>
	          <fDeleted>false</fDeleted>
	          <sTitle><![CDATA[Mode Control - control how the view displays the image]]></sTitle>
	        </interval>
	        <interval>
	           <ixInterval>230</ixInterval>
	           <ixPerson>2</ixPerson>
	           <ixBug>92</ixBug>
	           <dtStart>2009-09-23T18:18:11Z</dtStart>
	           <dtEnd>2009-09-23T19:25:00Z</dtEnd>
	           <fDeleted>false</fDeleted>
	           <sTitle><![CDATA[Requirements gathering]]></sTitle>
	        </interval>
	        <interval>
  	           <ixInterval>232</ixInterval>
		       <ixPerson>2</ixPerson>
		       <ixBug>102</ixBug>
		       <dtStart>2009-09-23T19:25:00Z</dtStart>
		       <dtEnd>2009-09-23T21:32:27Z</dtEnd>
		       <fDeleted>false</fDeleted>
		       <sTitle><![CDATA[Refactor blend mode and volume view]]></sTitle>
		    </interval>
		    <interval>
		       <ixInterval>233</ixInterval>
		       <ixPerson>2</ixPerson>
		       <ixBug>102</ixBug>
		       <dtStart>2009-09-24T12:46:26Z</dtStart>
		       <dtEnd>2009-09-24T13:06:34Z</dtEnd>
		       <fDeleted>false</fDeleted>
		       <sTitle><![CDATA[Refactor blend mode and volume view]]></sTitle>
		    </interval><interval><ixInterval>234</ixInterval><ixPerson>2</ixPerson><ixBug>102</ixBug><dtStart>2009-09-24T13:10:04Z</dtStart><dtEnd>2009-09-24T13:36:50Z</dtEnd><fDeleted>false</fDeleted><sTitle><![CDATA[Refactor blend mode and volume view]]></sTitle></interval>
		    <interval><ixInterval>235</ixInterval><ixPerson>2</ixPerson><ixBug>87</ixBug><dtStart>2009-09-24T13:38:22Z</dtStart><dtEnd>2009-09-24T13:58:00Z</dtEnd><fDeleted>false</fDeleted><sTitle><![CDATA[Mode Control - control how the view displays the image]]></sTitle></interval>
		    <interval><ixInterval>236</ixInterval><ixPerson>2</ixPerson><ixBug>102</ixBug><dtStart>2009-09-24T13:58:00Z</dtStart><dtEnd>2009-09-24T15:45:00Z</dtEnd><fDeleted>false</fDeleted><sTitle><![CDATA[Refactor blend mode and volume view]]></sTitle></interval>
		    <interval><ixInterval>237</ixInterval><ixPerson>2</ixPerson><ixBug>92</ixBug><dtStart>2009-09-24T15:45:00Z</dtStart><dtEnd>2009-09-24T16:05:00Z</dtEnd><fDeleted>false</fDeleted><sTitle><![CDATA[Requirements gathering]]></sTitle></interval>
		    <interval><ixInterval>238</ixInterval><ixPerson>2</ixPerson><ixBug>102</ixBug><dtStart>2009-09-24T17:10:00Z</dtStart><dtEnd>2009-09-24T17:30:29Z</dtEnd><fDeleted>false</fDeleted><sTitle><![CDATA[Refactor blend mode and volume view]]></sTitle></interval>
		    <interval><ixInterval>239</ixInterval><ixPerson>2</ixPerson><ixBug>102</ixBug><dtStart>2009-09-24T18:08:20Z</dtStart><dtEnd>2009-09-24T19:02:01Z</dtEnd><fDeleted>false</fDeleted><sTitle><![CDATA[Refactor blend mode and volume view]]></sTitle></interval>
		    <interval><ixInterval>240</ixInterval><ixPerson>2</ixPerson><ixBug>102</ixBug><dtStart>2009-09-24T19:50:59Z</dtStart><dtEnd>2009-09-24T20:11:44Z</dtEnd><fDeleted>false</fDeleted><sTitle><![CDATA[Refactor blend mode and volume view]]></sTitle></interval>
		    <interval><ixInterval>241</ixInterval><ixPerson>2</ixPerson><ixBug>102</ixBug><dtStart>2009-09-24T21:22:31Z</dtStart><dtEnd>2009-09-24T21:41:00Z</dtEnd><fDeleted>false</fDeleted><sTitle><![CDATA[Refactor blend mode and volume view]]></sTitle></interval>
		    <interval><ixInterval>245</ixInterval><ixPerson>2</ixPerson><ixBug>103</ixBug><dtStart>2009-09-24T21:41:00Z</dtStart><dtEnd>2009-09-24T22:00:00Z</dtEnd><fDeleted>false</fDeleted><sTitle><![CDATA[Upgrade image server to latest NIMS]]></sTitle></interval>
		    <interval><ixInterval>244</ixInterval><ixPerson>2</ixPerson><ixBug>103</ixBug><dtStart>2009-09-25T12:45:00Z</dtStart><dtEnd>2009-09-25T13:38:00Z</dtEnd><fDeleted>false</fDeleted><sTitle><![CDATA[Upgrade image server to latest NIMS]]></sTitle></interval>
		    <interval><ixInterval>242</ixInterval><ixPerson>2</ixPerson><ixBug>92</ixBug><dtStart>2009-09-25T13:38:59Z</dtStart><dtEnd>2009-09-25T13:45:00Z</dtEnd><fDeleted>false</fDeleted><sTitle><![CDATA[Requirements gathering]]></sTitle></interval>
		    <interval><ixInterval>243</ixInterval><ixPerson>2</ixPerson><ixBug>103</ixBug><dtStart>2009-09-25T13:45:00Z</dtStart><dtEnd>2009-09-25T15:09:54Z</dtEnd><fDeleted>false</fDeleted><sTitle><![CDATA[Upgrade image server to latest NIMS]]></sTitle></interval>
		    <interval><ixInterval>246</ixInterval><ixPerson>2</ixPerson><ixBug>87</ixBug><dtStart>2009-09-25T15:09:54Z</dtStart><dtEnd>2009-09-25T16:26:00Z</dtEnd><fDeleted>false</fDeleted><sTitle><![CDATA[Mode Control - control how the view displays the image]]></sTitle></interval>
		    <interval><ixInterval>247</ixInterval><ixPerson>2</ixPerson><ixBug>103</ixBug><dtStart>2009-09-25T16:26:00Z</dtStart><dtEnd>2009-09-25T17:30:00Z</dtEnd><fDeleted>false</fDeleted><sTitle><![CDATA[Upgrade image server to latest NIMS]]></sTitle></interval>
		    <interval><ixInterval>248</ixInterval><ixPerson>2</ixPerson><ixBug>87</ixBug><dtStart>2009-09-25T18:10:00Z</dtStart><dtEnd>2009-09-25T18:33:29Z</dtEnd><fDeleted>false</fDeleted><sTitle><![CDATA[Mode Control - control how the view displays the image]]></sTitle></interval>
		    <interval><ixInterval>249</ixInterval><ixPerson>2</ixPerson><ixBug>103</ixBug><dtStart>2009-09-25T18:45:00Z</dtStart><dtEnd>2009-09-25T19:42:30Z</dtEnd><fDeleted>false</fDeleted><sTitle><![CDATA[Upgrade image server to latest NIMS]]></sTitle></interval>
		    <interval><ixInterval>250</ixInterval><ixPerson>2</ixPerson><ixBug>87</ixBug><dtStart>2009-09-25T20:02:58Z</dtStart><dtEnd>2009-09-25T20:23:41Z</dtEnd><fDeleted>false</fDeleted><sTitle><![CDATA[Mode Control - control how the view displays the image]]></sTitle></interval>
		    <interval><ixInterval>251</ixInterval><ixPerson>2</ixPerson><ixBug>103</ixBug><dtStart>2009-09-25T20:23:41Z</dtStart><dtEnd>2009-09-25T20:52:43Z</dtEnd><fDeleted>false</fDeleted><sTitle><![CDATA[Upgrade image server to latest NIMS]]></sTitle></interval>
		    <interval><ixInterval>252</ixInterval><ixPerson>2</ixPerson><ixBug>87</ixBug><dtStart>2009-09-25T20:55:10Z</dtStart><dtEnd>2009-09-25T21:14:19Z</dtEnd><fDeleted>false</fDeleted><sTitle><![CDATA[Mode Control - control how the view displays the image]]></sTitle></interval>
		 </intervals>
	  </response> 
	 */
	
	private final static DateFormat inputDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ");
	private final static DateFormat dailyWorkFormat = new SimpleDateFormat("yyyy-MM-dd");
	private final static Logger log = Logger.getLogger(Interval.class.getName());
	
	private final static Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("CST"));

	private Calendar _start;
	private Calendar _end;
	private int _bugID;

	static
	{
		dailyWorkFormat.setCalendar(calendar);
	}
	
	public Interval(Element intervalNode) throws Exception
	{
		_start = parseDate(intervalNode, "dtStart");
		_end = parseDate(intervalNode, "dtEnd");
		_bugID = parseBugID(intervalNode);
	}

	private static Calendar parseDate(Element intervalNode, String tag) throws Exception {
		NodeList list = intervalNode.getElementsByTagName(tag);
		if(list.getLength() > 0)
		{
			String fbDate = list.item(0).getTextContent();
			if(fbDate.isEmpty())
			{
				return null;
			}
			
			try
			{
				fbDate = fbDate.replace('T', ' ');
				fbDate = fbDate.replace("Z", "-0000");
				Date dt = inputDateFormat.parse(fbDate);
				Calendar s = (Calendar)calendar.clone();
				s.setTime(dt);
				return s;
			}
			catch(Exception ex)
			{
				log.warning("Could not parse string to date: '" + fbDate + "'");
			}
			
		}
		return null;
	}
	
	private static int parseBugID(Element intervalNode) throws Exception
	{
		NodeList list = intervalNode.getElementsByTagName("ixBug");
		if(list.getLength() > 0)
		{
			String isBugVal = list.item(0).getTextContent();
			if(isBugVal.isEmpty())
			{
				return 0;
			}
			
			try
			{
				return Integer.parseInt(isBugVal);
			}
			catch(Exception ex)
			{
				log.warning("Could not parse string to integer: '" + isBugVal + "'");
			}
			
		}
		return 0;
	}
	
	public int getDurationSec()
	{
		if(!isCompleteInterval())
		{
			return 0;
		}
		return (int)((_end.getTimeInMillis() - _start.getTimeInMillis())/1000);
	}
	
	public Date getStart()
	{
		return _start.getTime();
	}
	
	public boolean isCompleteInterval()
	{
		return _end != null && _start != null;
	}
	
	public int getBugId()
	{
		return _bugID;
	}
	
	public static ArrayList<Interval> parseIntervals(Document responseDoc) throws Exception
	{
		ArrayList<Interval> intervals = new ArrayList<Interval>();
		NodeList list = responseDoc.getElementsByTagName("interval");
		for(int i = 0;i < list.getLength();++i)
		{
			Element intervalEl = (Element)list.item(i);
			intervals.add(new Interval(intervalEl));
		}
		
		return intervals;
	}
	
	public static DailyWork [] getDailyWorkSummary(Document responseDoc) throws Exception
	{
		TreeMap<String, DailyWork> dailyWorkMap = new TreeMap<String,DailyWork>();
		
		ArrayList<Interval> intervals = Interval.parseIntervals(responseDoc);
		
		for (Interval interval : intervals)
		{
			String workDayDate = dailyWorkFormat.format(interval.getStart());
			DailyWork dw;
			if(dailyWorkMap.containsKey(workDayDate))
			{
				dw = dailyWorkMap.get(workDayDate);
				dw.addTime(interval.getDurationSec());
			}
			else
			{
				dw = new DailyWork(dailyWorkFormat.parse(workDayDate), interval.getDurationSec());
				dailyWorkMap.put(workDayDate, dw);
			}
			
			if(!interval.isCompleteInterval())
			{
				dw.setWorkingOn(((Integer)interval.getBugId()).toString());
			}
		}
		
		Set<Entry<String, DailyWork>> mapSet = dailyWorkMap.entrySet();
		DailyWork [] dailyWork = new DailyWork[mapSet.size()];
		int i = 0;
		for(Entry<String, DailyWork> dailySummary : mapSet)
		{
			dailyWork[i++] = dailySummary.getValue();
		}
		
		return dailyWork;
	}
}
